Skip to content

Conversation

@simolus3
Copy link
Contributor

@simolus3 simolus3 commented Jan 28, 2026

This refactors how CREATE VIEW, CREATE TRIGGER and CREATE INDEX statements are constructed in powersync_replace_schema.

The main motivation here is that we want to be able to generate triggers for raw tables as well. At the moment, CREATE TRIGGER statements are built from a string template specialized for the type of trigger and table. To be able to re-use some of that logic for raw tables in the future, this adds the SqlBuffer utility. It contains several methods to write identifiers, string literals and common fragments into a String buffer. In particular, writing into powersync_crud and defining the "header" of CREATE TRIGGER statements has been refactored into common method calls instead of being a large string literal.

This PR doesn't change the statements generated by the core extension (apart from whitespace). It drastically reduces the amount of intermediate String allocations, but I don't expect that to have a meaningful impact on performance.

This also updates Rust to 1.93, to be able to use the standardized fmt::from_fn, allowing us to provide a callback responsible describing how to format a fragment.

@simolus3 simolus3 marked this pull request as draft January 28, 2026 17:21
@simolus3 simolus3 marked this pull request as ready for review January 29, 2026 10:23
@simolus3 simolus3 requested a review from rkistner January 29, 2026 10:24
Copy link
Contributor

@rkistner rkistner left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One edge case that this changes is a table that has both local_only: true and insert_only: true. As far as I can see, the previous logic just treated this as local_only, while the new logic treats this as a weird combination of the two, mostly behaving like insert_only.

Ideally we should just disallow specifying both flags, but that could be a breaking change (a user could easily have specified both accidentally before, and it would have kinda worked as a local-only table).

I'd suggest just modifying TableInfoFlags to consider insert_only as false in that case, and adding additional tests to check that case. Then we can consider that case as an error in the next major release.

@simolus3
Copy link
Contributor Author

while the new logic treats this as a weird combination of the two, mostly behaving like insert_only.

The insert trigger is the only one where it's a combination. For updates and deletes, we'd just skip the trigger for insert-only tables (so that branch would take precedence over the local-only check, which is a change).

I'd suggest just modifying TableInfoFlags to consider insert_only as false in that case, and adding additional tests to check that case

Done 👍

@simolus3 simolus3 merged commit 81404c5 into main Jan 29, 2026
25 checks passed
@simolus3 simolus3 deleted the sql-buffer branch January 29, 2026 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants